package com.example.ovulationperiodtracker.utils;

import com.example.ovulationperiodtracker.view.NoteUtils;
import com.tencent.mmkv.MMKV;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

public class CalendarUtils {

    private static final MMKV mmkv = MMKV.defaultMMKV();

    public static List<LocalDate> getPaiLuanRi() {

        String[] strings = mmkv.allKeys();
        if (strings == null) return new ArrayList<>();


        List<LocalDate> paiLuanRis = new ArrayList<>();
        int huangTiQi = NoteUtils.getHuangTiQi();
        List<NoteUtils.DayNote> allNotes12 = SexStatisticsUtils.getAllNotes12();

        for (int i = 0; i < allNotes12.size(); i++) {

            NoteUtils.DayNote dayNote = allNotes12.get(i);
            // 排卵日 下次月经日-14天（黄体期），易孕日是排卵日前5天和后4天 共10天
            if (dayNote.jingStart == 1) {
                LocalDate tempDate = LocalDate.parse(dayNote.date);
                //排卵日
                LocalDate paiLuanRi = tempDate.plusDays(-huangTiQi);
                paiLuanRis.add(paiLuanRi);
            }
        }

        //再加上往后一个月的预测易孕日
        List<LocalDate> allJingStart = NoteUtils.getAllJingStart();
        if(allJingStart.isEmpty()) return new ArrayList<>();
        LocalDate nearLocalData = allJingStart.get(0);

        int periodLength = NoteUtils.getPeriodLength();
        long months = Math.abs(ChronoUnit.MONTHS.between(nearLocalData, LocalDate.now()));

        for (int i = 0; i < 6 + months; i++) {
            nearLocalData = nearLocalData.plusDays(periodLength);
            LocalDate paiLuanRi = nearLocalData.plusDays(-huangTiQi);
            paiLuanRis.add(paiLuanRi);
        }

        return paiLuanRis;
    }

    public static List<LocalDate> getYiYunRi(List<LocalDate> pailunris) {
        String[] strings = mmkv.allKeys();
        if (strings == null) return new ArrayList<>();

        List<LocalDate> yiYunQi = new ArrayList<>();
        for (int i = 0; i < pailunris.size(); i++) {
            LocalDate paiLuanRi = pailunris.get(i);
            LocalDate yiYunRiStart = paiLuanRi.plusDays(-6);
            LocalDate yiYunRiEnd = paiLuanRi.plusDays(+4);
            LocalDate temp = yiYunRiEnd;
            while (temp.isAfter(yiYunRiStart)) {
                yiYunQi.add(temp);
                temp = temp.plusDays(-1);
            }
        }

        return yiYunQi;

    }


    public static List<LocalDate> getJingData() {
        String[] strings = mmkv.allKeys();
        if (strings == null) return new ArrayList<>();

        int periodLength = NoteUtils.getPeriodLength();
        List<LocalDate> allJingStart = NoteUtils.getAllJingStart();

        if(allJingStart.isEmpty()) return new ArrayList<>();
        //再添加今天往后一年预测的经期
        LocalDate localDate = allJingStart.get(0);

        long months = Math.abs(ChronoUnit.MONTHS.between(localDate, LocalDate.now()));

        for (int i = 0; i < 6 + months; i++) {
            localDate = localDate.plusDays(periodLength);
            allJingStart.add(0, localDate);
        }

        List<LocalDate> allJingEnd = NoteUtils.getAllJingEnd();

        List<LocalDate> allJing = new ArrayList<>();

        int jingLength = NoteUtils.getJingLength();
        for (int i = 0; i < allJingStart.size(); i++) {
            LocalDate start = allJingStart.get(i);
            //找出距离月经开始日 7天内最小的日期，既为月经结束日，如果没有则按照固定的长度预测
            LocalDate end = allJingEnd.stream()
                    // 过滤掉null元素
                    .filter(date -> date != null)
                    // 计算两个日期之间的天数差（取绝对值）
                    .filter(date -> Math.abs(ChronoUnit.DAYS.between(date, start)) <= 7)
                    // 找出最小的日期
                    .min(Comparator.naturalOrder())
                    // 若没有符合条件的日期，返回null
                    .orElse(null);

            if (end == null) {
                end = start.plusDays(jingLength - 1);
            }
            LocalDate current = start;
            while (!current.isAfter(end)) {
                allJing.add(current);
                current = current.plusDays(1); // 日期+1天
            }

        }

        return allJing;

    }

    //实际经期数据
    public static List<LocalDate> getJingShiJiData() {
        String[] strings = mmkv.allKeys();
        if (strings == null) return new ArrayList<>();

        List<LocalDate> allJingStart = NoteUtils.getAllJingStart();

        if(allJingStart.isEmpty()) return new ArrayList<>();

        List<LocalDate> allJingEnd = NoteUtils.getAllJingEnd();

        List<LocalDate> allJing = new ArrayList<>();

        for (int i = 0; i < allJingStart.size(); i++) {
            LocalDate start = allJingStart.get(i);
            allJing.add(start);
            //找出距离月经开始日 7天内最小的日期，既为月经结束日，如果没有则按照固定的长度预测
            LocalDate end = allJingEnd.stream()
                    // 过滤掉null元素
                    .filter(date -> date != null)
                    // 计算两个日期之间的天数差（取绝对值）
                    .filter(date -> Math.abs(ChronoUnit.DAYS.between(date, start)) <= 7)
                    // 找出最小的日期
                    .min(Comparator.naturalOrder())
                    // 若没有符合条件的日期，返回null
                    .orElse(null);

            if (end != null) {
                LocalDate current = start;
                while (!current.isAfter(end)) {
                    allJing.add(current);
                    current = current.plusDays(1); // 日期+1天
                }
            }
        }

        return allJing;

    }

    public static List<LocalDate> getYuChanQi() {

        String[] strings = mmkv.allKeys();
        if (strings == null) return new ArrayList<>();

        List<LocalDate> yiYunQi = new ArrayList<>();
        LocalDate yuChanQiStart = NoteUtils.getYuChanQiStart();
        LocalDate yuChanQi = NoteUtils.getYuChanQi();
        if (yuChanQiStart == null || yuChanQi == null) {
            return yiYunQi;
        }
        LocalDate temp = yuChanQi;
        while (temp.isAfter(yuChanQiStart)) {
            yiYunQi.add(temp);
            temp = temp.plusDays(-1);
        }
        return yiYunQi;
    }

}
